<template>
  <a-card :bordered="false">
    <div class="table-page-search-wrapper">
      <a-form layout="inline" :form="queryForm">
        <a-row :gutter="48">
          <a-col :md="8" :sm="24">
            <a-form-item label="类型名称">
              <a-input
                placeholder="类型名称"
                :maxLength="15"
                v-decorator="['dictName', { initialValue: this.queryParam.dictName }]"
              />
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="字典类型">
              <a-input
                placeholder="字典类型"
                :maxLength="20"
                v-decorator="['dictType', { initialValue: this.queryParam.dictType }]"
              />
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="是否有效">
              <a-select placeholder="请选择" v-decorator="['enabled', { initialValue: this.queryParam.enabled }]">
                <a-select-option value="">全部</a-select-option>
                <a-select-option value="true">有效</a-select-option>
                <a-select-option value="false">无效</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <span class="table-page-search-submitButtons">
              <a-button type="primary" @click="this.search">查询</a-button>
              <a-button style="margin-left: 8px" @click="resetForm">重置</a-button>
            </span>
          </a-col>
        </a-row>
      </a-form>
    </div>

    <div class="table-operator">
      <a-button type="primary" icon="plus" v-action:sys:dictType:add @click="add">新建</a-button>
      <a-button
        type="primary"
        :disabled="selectedRowKeys.length != 1"
        icon="edit"
        v-action:sys:dictType:update
        @click="edit()"
        >编辑</a-button
      >
      <a-button
        type="danger"
        :disabled="selectedRowKeys.length == 0"
        icon="delete"
        v-action:sys:dictType:delete
        @click="del"
        >删除</a-button
      >
    </div>
    <a-spin :spinning="loading">
      <s-table
        ref="table"
        size="middle"
        rowKey="id"
        :columns="columns"
        :data="loadData"
        bordered
        :rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
      >
        <span slot="action" slot-scope="text, record">
          <a href="javascript:;" @click="view(record.id)">查看</a>
          <span v-action:sys:dictType:update>
            <a-divider type="vertical" />
            <a href="javascript:;" @click="edit(record.id)">编辑</a>
          </span>
          <span v-action:sys:dictType:delete>
            <a-divider type="vertical" />
            <a href="javascript:;" @click="deletes(record.id)">删除</a>
          </span>
          <span>
            <a-divider type="vertical" />
            <a href="javascript:;" @click="viewDict(record.id)">查看字典</a>
          </span>
        </span>

        <span slot="dictTypeEnabled" slot-scope="enabled">
          <a-tag :color="enabled ? 'green' : 'red'">
            {{ enabled ? '有效' : '无效' }}
          </a-tag>
        </span>
      </s-table>
    </a-spin>
    <!--新增/修改/查看弹出层-->
    <a-modal
      :title="formDisabled ? '查看' : this.$isNull(this.formData) || this.$isNull(this.formData.id) ? '新增' : '更新'"
      :width="960"
      :visible="visible"
      :centered="true"
      :confirmLoading="loading"
      :maskClosable="false"
      :destroyOnClose="true"
      :keyboard="true"
      @cancel="visibleModal()"
    >
      <a-spin :spinning="loading">
        <a-form :form="form" :label-col="{ span: 5 }" :wrapper-col="{ span: 18 }">
          <a-row :gutter="24" style="display:none;">
            <a-col :span="24">
              <a-form-item label="主键">
                <a-input v-decorator="['id', { rules: [{ required: false }], initialValue: this.formData.id }]" />
              </a-form-item>
            </a-col>
          </a-row>
          <a-row :gutter="24">
            <a-col :span="12">
              <a-form-item label="字典名称">
                <a-input
                  :disabled="formDisabled"
                  :maxLength="15"
                  v-decorator="[
                    'dictName',
                    {
                      rules: [{ required: true, message: '请输入字典名称' }],
                      initialValue: this.formData.dictName
                    }
                  ]"
                  placeholder="请输入角字典名称"
                />
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="字典类型">
                <a-input
                  :maxLength="20"
                  :disabled="formDisabled"
                  v-decorator="[
                    'dictType',
                    {
                      rules: [{ required: true, message: '请输入字典类型' }, { validator: validatorExistDictType }],
                      initialValue: this.formData.dictType
                    }
                  ]"
                  placeholder="请输入字典类型"
                />
              </a-form-item>
            </a-col>
          </a-row>

          <a-row :gutter="24">
            <a-col :span="12">
              <a-form-item label="是否有效">
                <a-switch
                  :disabled="formDisabled"
                  checkedChildren="有效"
                  unCheckedChildren="无效"
                  v-decorator="[
                    'enabled',
                    {
                      valuePropName: 'checked',
                      rules: [{ required: true, message: '请选择是否有效' }],
                      initialValue: this.$isNull(this.formData.id) ? true : this.formData.enabled
                    }
                  ]"
                />
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="描述">
                <a-textarea
                  allow-clear
                  :disabled="formDisabled"
                  :autoSize="{ minRows: 5, maxRows: 6 }"
                  :maxLength="150"
                  placeholder="描述"
                  v-decorator="[
                    'description',
                    { rules: [{ required: false }], initialValue: this.formData.description }
                  ]"
                />
              </a-form-item>
            </a-col>
          </a-row>
        </a-form>
      </a-spin>
      <template slot="footer">
        <a-button key="back" @click="visibleModal()">
          返回
        </a-button>
        <a-button key="submit" type="primary" v-show="!formDisabled" :loading="loading" @click="save">
          保存
        </a-button>
      </template>
    </a-modal>

    <a-drawer
      title="字典管理"
      width="60%"
      :maskClosable="false"
      :closable="true"
      @close="closeDictManage"
      :visible="dictVisible"
      placement="right"
      :keyboard="true"
    >
      <a-form layout="inline" :form="dictQueryForm">
        <a-row :gutter="48">
          <a-col :md="8" :sm="12">
            <a-form-item label="字典名称">
              <a-input
                placeholder="字典名称"
                :maxLength="15"
                v-decorator="['name', { initialValue: this.queryDictParam.name }]"
              />
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="12">
            <a-form-item label="字典标识">
              <a-input
                placeholder="字典标识"
                :maxLength="20"
                v-decorator="['code', { initialValue: this.queryDictParam.code }]"
              />
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="12">
            <a-form-item label="是否有效">
              <a-select
                placeholder="请选择"
                style="width:200px"
                v-decorator="['enabled', { initialValue: this.queryDictParam.enabled }]"
              >
                <a-select-option value="">全部</a-select-option>
                <a-select-option value="true">有效</a-select-option>
                <a-select-option value="false">无效</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
        </a-row>
        <a-row :gutter="48" style="margin-top: 12px;">
          <a-col :md="12" :sm="24">
            <a-button type="primary" style="margin-right: 8px" @click="searchDict">查询</a-button>
            <a-button @click="resetSearchDict">重置</a-button>
          </a-col>
        </a-row>
      </a-form>

      <a-row :gutter="48" style="margin-top: 12px;">
        <a-col :md="12" :sm="24">
          <span class="table-page-search-submitButtons">
            <a-button type="primary" @click="editDict(null)" v-action:sys:dict:add>新建</a-button>
            <a-button
              v-action:sys:dict:update
              type="primary"
              :disabled="selectedDictRowKeys.length != 1"
              @click="editDict(selectedDictRowKeys[0])"
              style="margin-left: 8px"
              >编辑</a-button
            >
            <a-button
              type="danger"
              :disabled="selectedDictRowKeys.length == 0"
              icon="delete"
              style="margin-left: 8px"
              v-action:sys:dict:delete
              @click="deleteDict"
              >删除</a-button
            >
          </span>
        </a-col>
      </a-row>
      <a-row :gutter="48" style="margin-top: 12px;padding: 10px;">
        <s-table
          ref="dictTable"
          size="middle"
          rowKey="id"
          :columns="dictColumns"
          :data="dictLoadData"
          bordered
          :rowSelection="{ selectedRowKeys: selectedDictRowKeys, onChange: onSelectDictChange }"
        >
          <span slot="action" slot-scope="text, record">
            <a href="javascript:;" @click="viewDictFormData(record.id)">查看</a>
            <span v-action:sys:dictType:update>
              <a-divider type="vertical" />
              <a href="javascript:;" @click="editDict(record.id)">编辑</a>
            </span>
            <span v-action:sys:dictType:delete>
              <a-divider type="vertical" />
              <a href="javascript:;" @click="deletes(record.id)">删除</a>
            </span>
          </span>

          <span slot="dictEnabled" slot-scope="enabled">
            <a-tag :color="enabled ? 'green' : 'red'">
              {{ enabled ? '有效' : '无效' }}
            </a-tag>
          </span>
        </s-table>
      </a-row>
      <a-drawer
        :title="formDictDisabled ? '查看' : this.$isNull(this.dictFormData.id) ? '新增' : '更新'"
        width="35%"
        :closable="true"
        :maskClosable="false"
        @close="closeDictForm"
        :visible="dictFormVisible"
        placement="right"
      >
        <a-spin :spinning="this.dictFormLoading">
          <a-form :form="dictForm" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
            <a-row :gutter="24" style="display:none;">
              <a-col :span="24">
                <a-form-item label="主键">
                  <a-input v-decorator="['id', { rules: [{ required: false }], initialValue: this.dictFormData.id }]" />
                </a-form-item>
              </a-col>
            </a-row>
            <a-form-item label="字典名称">
              <a-input
                :disabled="formDictDisabled"
                :maxLength="15"
                v-decorator="[
                  'name',
                  { rules: [{ required: true, message: '请填写字典名称!' }], initialValue: this.dictFormData.name }
                ]"
              />
            </a-form-item>

            <a-form-item label="字典标识">
              <a-input
                :disabled="formDictDisabled"
                :maxLength="20"
                v-decorator="[
                  'code',
                  {
                    rules: [{ required: true, message: '请填写字典标识!' }, { validator: validatorExistDict }],
                    initialValue: this.dictFormData.code
                  }
                ]"
              />
            </a-form-item>
            <a-form-item label="排序">
              <a-input-number
                :disabled="formDictDisabled"
                style="width:100%"
                :min="1"
                :max="100"
                v-decorator="[
                  'sort',
                  {
                    rules: [{ required: false, message: '请输入显示顺序' }],
                    initialValue: this.$isNull(this.dictFormData.sort) ? 1 : this.dictFormData.sort
                  }
                ]"
              />
            </a-form-item>
            <a-form-item label="描述">
              <a-textarea
                :disabled="formDictDisabled"
                allow-clear
                :autoSize="{ minRows: 5, maxRows: 6 }"
                :maxLength="150"
                placeholder="描述"
                v-decorator="[
                  'description',
                  { rules: [{ required: false }], initialValue: this.dictFormData.description }
                ]"
              />
            </a-form-item>
            <a-form-item label="是否有效">
              <a-switch
                :disabled="formDictDisabled"
                checkedChildren="有效"
                unCheckedChildren="无效"
                v-decorator="[
                  'enabled',
                  {
                    valuePropName: 'checked',
                    rules: [{ required: true, message: '请选择是否有效' }],
                    initialValue: this.$isNull(this.dictFormData.enabled) ? true : this.dictFormData.enabled
                  }
                ]"
              />
            </a-form-item>
            <a-form-item :wrapper-col="{ span: 12, offset: 5 }">
              <a-button
                type="primary"
                @click="saveDict"
                :loading="dictLoading"
                v-show="!formDictDisabled"
                style="marginRight: 8px"
              >
                保存
              </a-button>
              <a-button @click="closeDictForm">
                返回
              </a-button>
            </a-form-item>
          </a-form>
        </a-spin>
      </a-drawer>

      <div
        :style="{
          position: 'absolute',
          bottom: 0,
          width: '100%',
          borderTop: '1px solid #e8e8e8',
          padding: '10px 16px',
          textAlign: 'right',
          left: 0,
          background: '#fff',
          borderRadius: '0 0 4px 4px'
        }"
      >
        <a-button @click="closeDictManage">
          返回
        </a-button>
      </div>
    </a-drawer>
  </a-card>
</template>

<script>
import { STable } from '@/components'
import { list, get, del, update, add, existDictType } from '@/api/system/dictType/dictType'
import {
  list as dictList,
  add as addDict,
  update as updateDict,
  existDict,
  get as getDict,
  del as deleDict
} from '@/api/system/dict/dict'
export default {
  name: 'DictType',
  components: {
    STable
  },
  data() {
    return {
      // 高级搜索 展开/关闭
      advanced: true,
      // 新增/修改用户弹出层
      visible: false,
      // 字典弹窗显示
      dictVisible: false,
      // 字典表单窗口
      dictFormVisible: false,
      // 禁用表单所有元素
      formDisabled: false,
      // 禁用字典元素数据
      formDictDisabled: false,
      // 用户 新增/编辑表单
      formData: {},
      // 字典表单数据
      dictFormData: {},
      // 数据表单
      form: this.$form.createForm(this),
      // 字典数据表单
      dictForm: this.$form.createForm(this),
      // 查询表单
      queryForm: this.$form.createForm(this),
      // 新增/编辑 弹出层加载
      loading: false,
      // 字典保存按钮加载
      dictLoading: false,
      // 字典表单加载按钮
      dictFormLoading: false,
      // 字典查询表单
      dictQueryForm: this.$form.createForm(this),
      // 查询参数
      queryParam: {
        pageIndex: 1,
        pageSize: 10,
        dictName: null,
        dictType: null,
        enabled: null
      },
      // 字典查询列表
      queryDictParam: {
        pageIndex: 1,
        pageSize: 10,
        name: null,
        code: null,
        enabled: null,
        dictTypeId: null
      },
      // 字典类型列表字段表头
      columns: [
        {
          title: '类型名称',
          dataIndex: 'dictName',
          width: '15%',
          ellipsis: true
        },
        {
          title: '字典类型',
          dataIndex: 'dictType',
          width: '15%'
        },
        {
          title: '是否有效',
          width: '10%',
          dataIndex: 'enabled',
          align: 'center',
          scopedSlots: { customRender: 'dictTypeEnabled' }
        },
        {
          title: '描述',
          width: '25%',
          dataIndex: 'description',
          ellipsis: true
        },
        {
          title: '创建时间',
          dataIndex: 'createTime',
          width: '18%',
          ellipsis: true
        },
        {
          title: '更新时间',
          dataIndex: 'updateTime',
          width: '18%',
          ellipsis: true
        },
        {
          title: '操作',
          key: 'action',
          align: 'center',
          width: '15%',
          scopedSlots: { customRender: 'action' }
        }
      ],

      // 字典列表
      dictColumns: [
        {
          title: '名称',
          dataIndex: 'name',
          width: '15%',
          ellipsis: true
        },
        {
          title: '编码',
          dataIndex: 'code',
          width: '15%',
          ellipsis: true
        },
        {
          title: '排序',
          dataIndex: 'sort',
          width: '15%',
          ellipsis: true
        },
        {
          title: '描述',
          dataIndex: 'description',
          width: '15%',
          ellipsis: true
        },
        {
          title: '是否有效',
          dataIndex: 'enabled',
          width: '15%',
          ellipsis: true,
          scopedSlots: { customRender: 'dictEnabled' }
        },
        {
          title: '创建时间',
          dataIndex: 'createTime',
          width: '15%',
          ellipsis: true
        },
        {
          title: '更新时间',
          dataIndex: 'updateTime',
          width: '15%',
          ellipsis: true
        },
        {
          title: '操作',
          key: 'action',
          align: 'center',
          width: '15%',
          scopedSlots: { customRender: 'action' }
        }
      ],
      // 加载数据方法 必须为 Promise 对象
      loadData: parameter => this.list(parameter),
      // 字典数据列表
      dictLoadData: dictParameter => this.dictList(dictParameter),
      selectedDictRowKeys: [],
      selectedDictRows: [],
      selectedRowKeys: [],
      selectedRows: []
    }
  },
  methods: {
    // 重置表单
    resetForm() {
      this.queryForm.resetFields()
      this.search()
    },
    // 重置查询字典条件
    resetSearchDict() {
      this.dictQueryForm.resetFields()
      this.searchDict()
    },
    // 查询数据
    search() {
      this.$refs.table.refresh(true)
    },
    // 字典列表查询
    searchDict() {
      this.$refs.dictTable.refresh(true)
    },
    // 列表查询数据
    list(params) {
      let queryParam = {}
      this.queryForm.validateFields((errors, values) => {
        queryParam = {
          ...this.queryParam,
          ...params,
          ...values
        }
      })
      return list(queryParam)
        .then(res => {
          return res.data
        })
        .catch(err => {
          console.log(err)
        })
        .finally(() => {
          this.onSelectChange([], [])
        })
    },
    // 字典数据列表
    dictList(params) {
      let queryParam = {}
      this.dictQueryForm.validateFields((errors, values) => {
        queryParam = {
          ...this.queryDictParam,
          ...params,
          ...values
        }
      })
      return dictList(queryParam)
        .then(res => {
          return res.data
        })
        .catch(err => {
          console.log(err)
        })
        .finally(() => {
          this.onSelectDictChange([], [])
        })
    },
    // 校验是否存在相同的字典类型
    validatorExistDictType(rule, value, callback) {
      if (!this.$isNull(value)) {
        existDictType(value, this.formData.id)
          .then(res => {
            if (res.data) {
              callback(new Error('字典标识已存在'))
            }
          })
          .catch(err => {
            console.log(err)
          })
          .finally(() => {
            callback()
          })
      } else {
        callback()
      }
    },
    // 校验是否存在相同的字典
    validatorExistDict(rule, value, callback) {
      if (!this.$isNull(value)) {
        existDict(this.queryDictParam.dictTypeId, value, this.dictFormData.id)
          .then(res => {
            if (res.data) {
              callback(new Error('字典标识已存在'))
            }
          })
          .catch(err => {
            console.log(err)
          })
          .finally(() => {
            callback()
          })
      } else {
        callback()
      }
    },
    // 选择数据
    onSelectChange(selectedRowKeys, selectedRows) {
      this.selectedRowKeys = selectedRowKeys
      this.selectedRows = selectedRows
    },
    // 选择字典
    onSelectDictChange(selectedRowKeys, selectedRows) {
      this.selectedDictRowKeys = selectedRowKeys
      this.selectedDictRows = selectedRows
    },
    // 新增
    add() {
      this.visibleModal()
    },
    // 编辑
    edit(id) {
      this.visibleModal(this.$isNull(id) ? this.selectedRowKeys[0] : id, null, false)
    },
    // 编辑字典
    editDict(id) {
      this.viewDictForm(id)
    },
    // 保存表单
    save(e) {
      e.preventDefault()
      this.form.validateFields((err, values) => {
        if (!err) {
          this.loading = true
          let promise = null
          if (!this.$isNull(values.id)) {
            promise = update(values)
          } else {
            promise = add(values)
          }
          promise
            .then(res => {
              if (res.code !== 200) {
                this.$message.error(res.msg)
              } else {
                this.visibleModal(null, res.msg, false)
              }
            })
            .catch(err => {
              console.log(err)
            })
            .finally(() => {
              this.loading = false
            })
        }
      })
    },
    // 确认删除
    del() {
      const _this = this
      this.$confirm({
        centered: true,
        content: h => (
          <div>
            确认删除当前选中的 <b style="color:red;">{this.selectedRowKeys.length}</b> 条数据?
          </div>
        ),
        onOk() {
          _this.deletes(_this.selectedRowKeys.join(','))
        },
        onCancel() {
          _this.search()
        },
        class: 'deleteConfirm'
      })
    },
    // 删除字典
    deleteDict() {
      const _this = this
      this.$confirm({
        centered: true,
        content: h => (
          <div>
            确认删除当前选中的 <b style="color:red;">{this.selectedDictRowKeys.length}</b> 条数据?
          </div>
        ),
        onOk() {
          _this.deleteDicts(_this.selectedDictRowKeys.join(','))
        },
        onCancel() {
          _this.searchDict()
        },
        class: 'deleteConfirm'
      })
    },
    // 删除数据
    deletes(ids) {
      del(ids)
        .then(res => {
          if (res.code !== 200) {
            this.$message.error(res.msg)
          } else {
            this.onSelectChange([], [])
          }
        })
        .catch(err => {
          console.log(err)
        })
        .finally(() => {
          this.search()
        })
    },
    // 删除字典
    deleteDicts(ids) {
      deleDict(ids)
        .then(res => {
          if (res.code !== 200) {
            this.$message.error(res.msg)
          }
        })
        .catch(err => {
          console.log(err)
        })
        .finally(() => {
          this.searchDict()
        })
    },
    saveDict(e) {
      e.preventDefault()
      this.dictForm.validateFields((err, values) => {
        if (err) {
          return false
        }
        this.dictLoading = true
        let promise = null
        values.dictTypeId = this.queryDictParam.dictTypeId
        if (!this.$isNull(values.id)) {
          promise = updateDict(values)
        } else {
          promise = addDict(values)
        }
        promise
          .then(res => {
            if (res.code !== 200) {
              this.$message.error(res.msg)
            } else {
              this.closeDictForm()
            }
          })
          .catch(err => {
            console.log(err)
          })
          .finally(() => {
            this.dictLoading = false
          })
      })
    },
    // 查看详情
    view(id) {
      this.visibleModal(id, null, true)
    },
    // 查看字典数据
    viewDict(dictTypeId) {
      this.dictVisible = !this.dictVisible
      this.queryDictParam = {
        ...this.queryDictParam,
        dictTypeId
      }
      if (!this.$isNull(this.$refs.dictTable)) {
        this.searchDict()
      }
    },
    // 关闭字典管理
    closeDictManage() {
      this.dictVisible = !this.dictVisible
      this.dictFormData = {}
    },
    // 关闭字典表单
    closeDictForm() {
      this.dictForm.resetFields()
      if (this.dictFormVisible) {
        this.searchDict()
      }
      this.dictFormVisible = !this.dictFormVisible
      this.dictFormData = {}
      this.formDictDisabled = false
    },
    // 字典表单新增/编辑
    viewDictForm(id) {
      this.closeDictForm()
      if (!this.$isNull(id)) {
        this.dictFormLoading = !this.dictFormLoading
        getDict(id)
          .then(res => {
            if (res.code !== 200) {
              this.$message.error(res.msg)
              return
            }
            this.dictFormData = res.data
          })
          .finally(() => {
            this.dictFormLoading = !this.dictFormLoading
          })
      }
    },
    // 查看字典
    viewDictFormData(id) {
      this.viewDictForm(id)
      this.formDictDisabled = true
    },
    // 关闭新增/编辑/查看弹出层
    visibleModal(id, message, formDisabled) {
      if (this.visible) {
        this.search()
      } else {
        this.loading = true
        this.formDisabled = this.$isNull(formDisabled) ? false : formDisabled
        this.formData = {}
      }
      if (this.$isNull(id)) {
        this.loading = false
        this.visible = !this.visible
      } else {
        get(id)
          .then(res => {
            if (res.code !== 200) {
              this.$message.error(res.msg)
              this.search()
              return
            }
            this.visible = !this.visible
            this.formData = this.$isNull(res.data) ? {} : res.data
            if (!this.$isNull(message)) {
              this.$message.success(message)
            }
          })
          .catch(err => {
            console.log(err)
          })
          .finally(() => {
            this.loading = false
          })
      }
    },
    // 选择菜单
    menuCheck(checkedKeys, info) {
      this.form.setFieldsValue({
        menuIds: checkedKeys.checked.join(',')
      })
    }
  }
}
</script>

<style lang="less" scoped>
.search {
  margin-bottom: 54px;
}

.fold {
  width: calc(100% - 216px);
  display: inline-block;
}

.operator {
  margin-bottom: 18px;
}

@media screen and (max-width: 900px) {
  .fold {
    width: 100%;
  }
}
.ant-calendar-picker {
  width: 358px !important;
}
</style>
